package com.topnav.mc.config;

//import com.alibaba.fastjson.parser.ParserConfig;
import com.js.lib.cache.RedisTemplateUtil;
import com.js.lib.config.RedisConfigProperties;
import com.topnav.mc.uitls.FastJsonRedisSerializer;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * 暂不用这个
 */
//@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    private RedisConfigProperties redisPropertis;

    public RedisConfig(RedisConfigProperties redisPropertis){
        this.redisPropertis = redisPropertis;
    }

    @Autowired
    private JedisPoolConfig jedisPoolConfig;

    @Autowired
    private JedisConnectionFactory jedisConnectionFactory;

    @Autowired
    private RedisTemplate redisTemplate;
/*

    @Bean
    public JedisPoolConfig jedisPoolConfig(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setBlockWhenExhausted(true);//连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
        jedisPoolConfig.setJmxEnabled(true);//是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setTestOnReturn(true);//jedis调用returnObject方法时，是否进行有效检查
        jedisPoolConfig.setLifo(true);//是否启用后进先出，默认true
        jedisPoolConfig.setMaxIdle(redisPropertis.getMaxIdle());//最大空闲连接数
        jedisPoolConfig.setMaxTotal(redisPropertis.getMaxTotal());//最大连接数
        */
/** 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1*//*

        //jedisPoolConfig.setMaxWaitMillis(-1);
        jedisPoolConfig.setMaxWaitMillis(redisPropertis.getMaxWait() * 1000L);
        */
/** 逐出连接的最小空闲时间 默认1800000毫秒(30分钟) *//*

        jedisPoolConfig.setMinEvictableIdleTimeMillis(1800000);
        jedisPoolConfig.setMinIdle(redisPropertis.getMinIdle());//最小空闲连接数
        */
/** 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3 *//*

        jedisPoolConfig.setNumTestsPerEvictionRun(3);
        */
/** 对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断  (默认逐出策略) *//*

        jedisPoolConfig.setSoftMinEvictableIdleTimeMillis(1800000);
        */
/** 在获取连接的时候检查有效性, 默认false *//*

        jedisPoolConfig.setTestOnBorrow(redisPropertis.isTestOnBorrow());
        */
/** 在空闲时检查有效性, 默认false *//*

        jedisPoolConfig.setTestWhileIdle(false);
        */
/** 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1 *//*

        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(-1);
        return jedisPoolConfig;
    }
*/

    @Bean
    public JedisPool jedisPool() {
        String password = redisPropertis.getSingle().getPwd();
        if (StringUtils.isBlank(password)) {
            password = null;
        }
/*
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(redisPropertis.getMaxIdle());
        poolConfig.setMaxTotal(redisPropertis.getMaxTotal());
        // 秒转毫秒
        poolConfig.setMaxWaitMillis(redisPropertis.getMaxWait() * 1000L);
*/

        JedisPool jp = new JedisPool(jedisPoolConfig, redisPropertis.getSingle().getHost(),redisPropertis.getSingle().getPort(), redisPropertis.getTimeout() * 1000, password, redisPropertis.getDatabase());
        return jp;
    }

    /**
     * 启用redis才注入
     */
/*    @SuppressWarnings("deprecation")
    @ConditionalOnProperty(prefix="redis",name="active",havingValue="true",matchIfMissing = false)
    @Bean
    public JedisConnectionFactory jedisConnectionFactory(){
        JedisConnectionFactory jedisConnectionFactory;// = new JedisConnectionFactory(jedisPoolConfig());

        *//** 集群模式 *//*
        if ("cluster".equalsIgnoreCase(redisPropertis.getModel())){
            Set<String> nodes = new HashSet<String>();
            Collections.addAll(nodes, redisPropertis.getCluster().getNodes().split(","));
            RedisClusterConfiguration configuration = new RedisClusterConfiguration(nodes);
            configuration.setMaxRedirects(redisPropertis.getCluster().getMaxRedirects());
            configuration.setPassword(redisPropertis.getSentinel().getPassword());
            jedisConnectionFactory = new JedisConnectionFactory(configuration,jedisPoolConfig);
            //jedisConnectionFactory.setUsePool(true);
            //jedisConnectionFactory.setTimeout(redisPropertis.getTimeout());
        }else if ("sentinel".equalsIgnoreCase(redisPropertis.getModel())){
            *//** 哨兵模式 *//*
            Set<String> nodes = new HashSet<String>();
            Collections.addAll(nodes, redisPropertis.getSentinel().getNodes().split(","));
            RedisSentinelConfiguration configuration =
                    new RedisSentinelConfiguration(redisPropertis.getSentinel().getMasterName(),nodes);
            configuration.setPassword(redisPropertis.getSentinel().getPassword());
            configuration.setDatabase(redisPropertis.getDatabase());
*//*			configuration.setUsePool(true);
			configuration.setTimeout(redisPropertis.getTimeout());	*//*
            jedisConnectionFactory = new JedisConnectionFactory(configuration,jedisPoolConfig);
            //jedisConnectionFactory.setPassword(redisPropertis.getSentinel().getPassword());
            //jedisConnectionFactory.setUsePool(true);
            //jedisConnectionFactory.setTimeout(redisPropertis.getTimeout());
        }else {
            *//** 单例模式 *//*
*//*            RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(
                    redisPropertis.getSingle().getHost(),
                    redisPropertis.getSingle().getPort());
            configuration.setPassword(redisPropertis.getSingle().getPwd());
            configuration.setDatabase(redisPropertis.getDatabase());*//*
            jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
            jedisConnectionFactory.setHostName(redisPropertis.getSingle().getHost());
            jedisConnectionFactory.setPort(redisPropertis.getSingle().getPort());
            jedisConnectionFactory.setPassword(redisPropertis.getSingle().getPwd());
            jedisConnectionFactory.setDatabase(redisPropertis.getDatabase());
*//*			jedisConnectionFactory.setHostName(redisPropertis.getSingle().getHost());
			jedisConnectionFactory.setPort(redisPropertis.getSingle().getPort());*//*
            //jedisConnectionFactory.setPassword(redisPropertis.getSingle().getPwd());

        }
        jedisConnectionFactory.setUsePool(true);
        jedisConnectionFactory.setTimeout(redisPropertis.getTimeout());
        return jedisConnectionFactory;
    }*/
/*
    @ConditionalOnProperty(prefix="redis",name="active",havingValue="true",matchIfMissing = false)
    @SuppressWarnings({ "unchecked", "rawtypes" })
    //@Bean
    @Bean("redisTemplate")
    //public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    public RedisTemplate redisTemplate(){
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        //template.setConnectionFactory(redisConnectionFactory);
        template.setConnectionFactory(jedisConnectionFactory);

        // 使用fastjson进行序列化处理，提高解析效率
        FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<Object>(Object.class);
        // value值的序列化采用fastJsonRedisSerializer
        template.setValueSerializer(serializer);
        template.setHashValueSerializer(serializer);
        // key的序列化采用StringRedisSerializer
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setConnectionFactory(jedisConnectionFactory);
        // 使用fastjson时需设置此项，否则会报异常not support type
        //ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

        *//** 使用设置生效 *//*
        template.afterPropertiesSet();

        return template;
    }*/

    /**
     * redis消息监听器容器 可以添加多个监听不同话题的redis监听器，只需要把消息监听器和相应的消息订阅处理器绑定，该消息监听器
     * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
     *
     * @return
     */
    @ConditionalOnProperty(prefix="redis",name="active",havingValue="true",matchIfMissing = false)
    @Bean
    RedisMessageListenerContainer container() {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(jedisConnectionFactory);
        return container;
    }

    @ConditionalOnProperty(prefix="redis",name="active",havingValue="true",matchIfMissing = false)
    @Bean
    public RedisTemplateUtil redisTemplateUtil(){

        return new RedisTemplateUtil(redisTemplate);
    }
}
